/*
 * Copyright (C) 2010 TopCoder Inc., All Rights Reserved.
 */
package com.hercules.android.receiver.commands.call.animate;

import android.graphics.Matrix;
import android.os.Handler;
import android.view.animation.AnimationSet;
import android.view.animation.AnimationUtils;
import android.view.animation.RotateAnimation;
import android.view.animation.ScaleAnimation;
import android.view.animation.Transformation;
import android.view.animation.TranslateAnimation;

import com.hercules.android.receiver.Receiver;
import com.hercules.android.receiver.ReceiverUtil;
import com.hercules.android.receiver.commands.XRECommandHandlerException;
import com.hercules.android.receiver.entities.XREObject;
import com.hercules.android.receiver.entities.XRETransformAnimation;
import com.hercules.android.receiver.entities.XREView;

/**
 * <p>
 * This class will handle the XRETransformAnimation animation.
 * </p>
 * 
 * @author TCSASSEMBER
 * @version 1.0
 */
public class XREHandlerTransformAnimate implements XREHandlerAnimate {
    /**
     * Handle the animate call command message.
     * 
     * @param targetView
     *            the target view need to animate
     * @param animationResource
     *            the animation resource
     * @param receiver
     *            the <code>Receiver</code> instance.
     * @throws XRECommandHandlerException
     *             if any error occurs
     */
    public void handle(final XREView targetView, final XREObject animationResource, final Receiver receiver)
            throws XRECommandHandlerException {
        XRETransformAnimation animation = (XRETransformAnimation) animationResource;

        final AnimationSet set = new AnimationSet(false);
        if (animation.getX() != 0 || animation.getY() != 0) {
            TranslateAnimation translateAnimation = new TranslateAnimation(0.0f, (float) animation.getX(), 0.0f,
                    (float) animation.getY());
            translateAnimation.setDuration(animation.getDuration());
            set.addAnimation(translateAnimation);
        }
        if (animation.getScaleX() != 1.0 || animation.getScaleY() != 1.0) {
            ScaleAnimation scaleAnimation = new ScaleAnimation(1.0f, animation.getScaleX().floatValue(), 1.0f,
                    animation.getScaleY().floatValue(), animation.getActionPointX().floatValue(), animation
                            .getActionPointY().floatValue());
            scaleAnimation.setDuration(animation.getDuration());
            set.addAnimation(scaleAnimation);
        }
        if (animation.getRotation() != 0.0) {
            RotateAnimation rotateAnimation = new RotateAnimation(0.0f,
                    (float) (animation.getRotation() * 180 / Math.PI), animation.getActionPointX().floatValue(),
                    animation.getActionPointY().floatValue());
            rotateAnimation.setDuration(animation.getDuration());
            set.addAnimation(rotateAnimation);
        }
        set.setDuration(animation.getDuration());
        set.initialize(targetView.getDimensions()[0], targetView.getDimensions()[1], receiver
                .getApplicationConnectionData().getDeviceCaps().getNativeDimensions()[0], receiver
                .getApplicationConnectionData().getDeviceCaps().getNativeDimensions()[1]);
        final Matrix oriMatrix = new Matrix();
        oriMatrix.setValues(targetView.getMatrix());

        new Thread(new Runnable() {
            /**
             * The method function of the thread. It will update the states of
             * the target and update the root view.
             */
            public void run() {
                Transformation transformation = new Transformation();
                while (true) {
                    if (set.hasEnded()) {
                        return;
                    }
                    set.getTransformation(AnimationUtils.currentAnimationTimeMillis(), transformation);
                    Matrix matrix = new Matrix(oriMatrix);
                    matrix.postConcat(transformation.getMatrix());
                    matrix.getValues(targetView.getMatrix());
                    // redraw the view
                    Handler mHandler = receiver.getApplicationData().getRootViewUpdateHandler();
                    mHandler.sendMessage(mHandler.obtainMessage());
                    ReceiverUtil.animateSleep();
                }
            }
        }).start();

        set.startNow();
    }
}
